Go best practises

I have been building the back-end for Endless, a product we make at Studio March, primarily in Go. There have been a few pleasant surprises that the language provides. Here I try to explain an opinionated best practises while coding in Go.

Use the standard library.

Always see if there is something in the standard library that fits your need before looking else where. In most cases the standard library is just enough.

The flag package for most configurations.

The flag package is seen as parsing arguments from the command line. It can also be used to store configurations your code might need. It also helps serve documentation for all the configurations.

var port int
flag.IntVar(&port, "port", 8000, "Specifies the port the server listens to.")

This can either be used as command line arguments or in places which needs default values.

The database/sql as a substitute for the many ORMs

I searched for days to stick to an ORM but finally decided to stick with the vanilla database/sql package. Many might think this takes us back a step but its simplicity makes up for any drawback. ORMs generally take the least common set of features a database provides. For example you cannot take advantages that Postgres give you with Hstore or Array data types. With the database/sql you can.

I use the net/http

For my needs the net/http fits well for the few end points of the API. Sometimes I use the Gorilla tool kit when the http package is not enough. More than a full fledge framework use what you need from the net/http package or the toolkit.

others

The log package does most of your logging at ease. It is also thread safe which means you can have global Loggers to do all your logging. Use the log.Lshortfile flag for debugging purposes. The testing suite with the go test command is enough for most test cases.

Use the tools provided with go

Go provides tools like gofmt go test which ease up your development, use them effectively.

gofmt

If you have programmed with Go before you will know that the language designers decided to put a full stop in styling discussions with the gofmt tool. The tool decides how many tabs, spaces between parenthesis and all the non-essential discussions. But you might have missed the wonderful option which can be used to re-factor your code. The -r option just does that.

gofmt -r 'pattern -> replacement' <files>

Thus if you want to change a struct Program to Process you would

gofmt -r 'Program -> Process' -w .

If you just want to list the files that contain the changes use a -l. Use godoc gofmt to learn more.

go test

The test suite of go has a lot of gems hidden. I use the -test.run=TestFunction many times. The tool also provides coverage and benchmark analysis. The several tools go provides are useful and enough for most cases. Do read the documentation of these tools. I'm sure you will find some that surprise you.

Organize your Go code

The Go language internally uses a format which we can follow nearly. Go files that expose a main package, that is one that builds an executable, reside inside cmd folder and libraries inside pkg folder. We can use the cmd folder to store executables and the root folder(we don't need to use the pkg folder to simplify import paths). So if we were creating a web server we could do something like this:

cmd/
    endless/
            main.go
            api.go
            ...
models.go
db.go
...

This way in our endless/main.go we can use an import path like github.com/endless/models etc.

And a few others

Use environment variables for sensitive information

Use the os.Getenv("VARIABLE_NAME") to set passwords and other sensitive in your program. This way you avoid pushing passwords in your versioning system.

Use your $HOME folder for $GOPATH

This is just convenience. Setting it will automatically put binaries in $HOME/bin and navigating through code can be easier by just following $HOME/src.

Naming conventions

Follow standards in Effective Go for naming conventions. Try to make your packages read like users.New or sessions.DB.

Keep it simple

The beauty of Go is its simplicity, so try to do the same with your code. Avoid exposing too many variables/structs/functions. Make your API small and simple. This makes it easier to maintain your code.

As I keep coding in Go I learn something new every day. This is definitely not an exhaustive list and some of it is opinionated, take it with a pinch of salt. One good advice is to try the idiomatic way of Go. Almost always the designers have got it right.

Created on Nov 23 2014